﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Data;
using System.IO;
using System.Xml;
using System.Xml.Schema;


namespace XMLValidator
{

    public static class XMLValidate
    {
        static int numErrors = 0;
        static string msgError = "";

        public static bool Validate(Stream xml, string xsdFilename)
        {
            return Validate(xml, GetFileStream(xsdFilename));
        }
        public static bool Validate(string xmlFilename, Stream xsd)
        {
            return Validate(GetFileStream(xmlFilename), xsd);
        }
        public static bool Validate(string xmlFilename, string xsdFilename)
        {
            return Validate(GetFileStream(xmlFilename), GetFileStream(xsdFilename));
        }
        public static bool Validate(Stream xml, Stream xsd)
        {
            ClearErrorMessage();
            try
            {
                XmlTextReader tr = new XmlTextReader(xsd);
                XmlSchemaSet schema = new XmlSchemaSet();
                schema.Add(null, tr);

                XmlReaderSettings settings = new XmlReaderSettings();
                settings.ValidationType = ValidationType.Schema;
                settings.Schemas.Add(schema);
                settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
                settings.ValidationEventHandler += new ValidationEventHandler(ErrorHandler);
                XmlReader reader = XmlReader.Create(xml, settings);

                // Validate XML data
                while (reader.Read());
                reader.Close();

                // exception if validation failed
                if (numErrors > 0)
                {
                    throw new Exception(msgError);
                }
                else
                {
                    Console.WriteLine("The XML is validated!");
                }

                return true;
            }
            catch
            {
                msgError = "Validation failed\r\n" + msgError;
                Console.WriteLine(msgError);
                return false;
            }
        }

        private static void ErrorHandler(object sender, ValidationEventArgs args)
        {
            msgError = msgError + "\r\n" + args.Message;
            numErrors++;
        }

        // if a validation error occurred, this will return the message
        public static string GetError()
        {
            return msgError;
        }

        private static void ClearErrorMessage()
        {
            msgError = "";
            numErrors = 0;
        }

        // returns a stream of the contents of the given filename
        private static Stream GetFileStream(string filename)
        {
            try
            {
                return new FileStream(filename, FileMode.Open);
            }
            catch
            {
                return null;
            }
        }
    }
}
